package com.samon.netty.echo;
/*
               _.---..._
           ./^         ^-._
         ./^C===.         ^\.   /\
        .|'     \\        _ ^|.^.|
   ___.--'_     ( )  .      ./ /||
  /.---^T\      ,     |     / /|||
 C'   ._`|  ._ /  __,-/    / /-,||
      \ \/    ;  /O  / _    |) )|,
       i \./^O\./_,-^/^    ,;-^,'
        \ |`--/ ..-^^      |_-^
         `|  \^-           /|:
          i.  .--         / '|.
           i   =='       /'  |\._
         _./`._        //    |.  ^-ooo.._
  _.oo../'  |  ^-.__./X/   . `|    | d
				 比克叔叔保佑
				 代码无BUG!
 */

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.InetSocketAddress;

/**
 * @author Mr.Wu on 2018/9/14
 */
public class EchoServer {
	
	private final int port;

	public EchoServer(int port) {
		this.port = port;
	}

	public static void main(String[] args) throws Exception {
		
		int port = 8888;
		new EchoServer(port).start();
	}
	
	public void start() throws Exception {

		final EchoServerHandler serverHandler = new EchoServerHandler();
		// 1. 创建 EventLoopGroup
		EventLoopGroup group = new NioEventLoopGroup();
		try {
			// 2. 创建 ServerBootstrap
			ServerBootstrap b = new ServerBootstrap();
			b.group(group)
			 // 3. 指定所使用的NIO传输channel
			 .channel(NioServerSocketChannel.class)
			 // 4. 使用指定的端口商团套接字地址
			 .localAddress(new InetSocketAddress(port))
			 // 5. 添加一个 EchoServerHandler(自己实现的) 到 子Channel 的 ChannelPipeline 管道
			 .childHandler(new ChannelInitializer<SocketChannel>() {
	
				 @Override protected void initChannel(SocketChannel socketChannel) {
				 	// EchoServerHandler 被标注为@Shareable, 所以我们可以总是使用同样的实例
					 socketChannel.pipeline().addLast(serverHandler);
				 }
			 });

			// 6. 异步绑定服务器; 调用sync()方法阻塞等待直到绑定完成
			ChannelFuture f = b.bind().sync();
			// 7. 获取 Channel 的 CloseFuture, 并且阻塞当前线程直到它完成
			f.channel().closeFuture().sync();
		} finally {
			// 8. 关闭 EventLoopGroup, 释放所有的资源
			group.shutdownGracefully().sync();
		}

	}
	
	
}
